using System.Collections.Generic;
using NHibernate.Expression;

namespace Project.Library.ActiveRecord.Repositories
{
    public interface IActiveRecordRepository<T> where T : class
    {
        bool UseAutoFlush { get; set; }

        /// <summary>
        /// Existses the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        bool Exists(T entity);

        /// <summary>
        /// Existses the specified where.
        /// </summary>
        /// <param name="where">The where.</param>
        /// <returns></returns>
        bool Exists(DetachedCriteria where);

        /// <summary>
        /// Existses the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        bool Exists(object id);

        /// <summary>
        /// Counts this instance.
        /// </summary>
        /// <returns></returns>
        int Count();

        /// <summary>
        /// Counts the specified where.
        /// </summary>
        /// <param name="where">The where.</param>
        /// <returns></returns>
        int Count(DetachedCriteria where);

        /// <summary>
        /// Finds all.
        /// </summary>
        /// <returns></returns>
        IList<T> FindAll();

        /// <summary>
        /// Finds all.
        /// </summary>
        /// <param name="where">The where.</param>
        /// <returns></returns>
        IList<T> FindAll(DetachedCriteria where);

        /// <summary>
        /// Finds all.
        /// </summary>
        /// <param name="firstResult">The first result.</param>
        /// <param name="maxResult">The max result.</param>
        /// <param name="where">The where.</param>
        /// <returns></returns>
        IList<T> FindAll(int firstResult, int maxResult, DetachedCriteria where);

        /// <summary>
        /// Gets the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        T Get(object id);

        /// <summary>
        /// Loads the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        T Load(object id);

        /// <summary>
        /// Finds the first.
        /// </summary>
        /// <param name="where">The where.</param>
        /// <returns></returns>
        T FindFirst(DetachedCriteria where);

        /// <summary>
        /// Finds the first.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <returns></returns>
        T FindFirst(Order[] order);

        /// <summary>
        /// Saves the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        T Save(T entity);

        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        T Update(T entity);

        /// <summary>
        /// Saves the or update.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        T SaveOrUpdate(T entity);

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Delete(T entity);

        /// <summary>
        /// Deletes all.
        /// </summary>
        void DeleteAll();

        /// <summary>
        /// Deletes all.
        /// </summary>
        /// <param name="with">The with.</param>
        void DeleteAll(DetachedCriteria with);

        /// <summary>
        /// Creates the detached criteria.
        /// </summary>
        /// <returns></returns>
        DetachedCriteria CreateDetachedCriteria();

        /// <summary>
        /// Creates the detached criteria.
        /// </summary>
        /// <param name="alias">The alias.</param>
        /// <returns></returns>
        DetachedCriteria CreateDetachedCriteria(string alias);
    }
}